package cn.elwy.rcp.ui.config;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import cn.elwy.common.exception.RunException;
import cn.elwy.osgi.config.ConfigPath;
import cn.elwy.rcp.core.model.ui.DialogInfo;
import cn.elwy.rcp.core.model.ui.DialogType;

public class DialogConfigFactory {

  private static final Map<DialogType, DialogInfo> dialogInfoMap = new HashMap<DialogType, DialogInfo>();
  private static final Map<String, DialogInfo> dialogInfoCacheMap = new HashMap<String, DialogInfo>();
  private static Map<String, DialogConfigAdapter> dialogInfoAdapterMap = new HashMap<String, DialogConfigAdapter>();
  private static DialogConfigAdapter defaultDialogInfoAdapter = new DialogConfigAdapter();

  private DialogConfigFactory() {
  }

  static {
    new DialogConfigParser().load();
  }

  public static Map<DialogType, DialogInfo> getDialogInfoMap() {
    return dialogInfoMap;
  }

  public static DialogInfo getDialogInfo(String dialogId, DialogType dialogType) {
    Object subjectId = ConfigPath.getSubjectId(true);
    String customKey = getCustomKey(subjectId, dialogId);
    // 从缓存获取
    DialogInfo dialogInfo = dialogInfoCacheMap.get(customKey);
    if (dialogInfo != null) {
      return dialogInfo;
    } else if (subjectId != null) {
      dialogInfo = dialogInfoCacheMap.get(dialogId);
    }
    if (dialogInfo != null) {
      return dialogInfo;
    }

    dialogInfo = getDialogInfo(subjectId, dialogId);
    if (dialogInfo == null && subjectId != null) {
      customKey = getCustomKey(null, dialogId);
      dialogInfo = getDialogInfo(null, dialogId);
    }
    if (dialogInfo == null) {
      // 复制扩展点的配置
      dialogInfo = newDialogInfo(dialogInfoMap.get(dialogType));
    }
    dialogInfo.setId(dialogId);
    dialogInfoCacheMap.put(customKey, dialogInfo);
    return dialogInfo;
  }

  public static void saveDialogInfo(DialogInfo dialogInfo) {
    Object subjectId = ConfigPath.getSubjectId(dialogInfo.isCanCustomConfig());
    saveDialogInfo(subjectId, dialogInfo);
  }

  public static DialogInfo newDialogInfo(DialogInfo source) {
    DialogInfo target = new DialogInfo();
    try {
      BeanUtils.copyProperties(target, source);
    } catch (Exception e) {
      throw new RunException(e.getMessage(), e);
    }
    return target;
  }

  public static Map<String, DialogConfigAdapter> getDialogInfoAdapterMap() {
    return dialogInfoAdapterMap;
  }

  public static void addDialogInfoAdapter(String tableId, DialogConfigAdapter dialogConfigAdapter) {
    dialogInfoAdapterMap.put(tableId, dialogConfigAdapter);
  }

  public static DialogConfigAdapter getDefaultDialogInfoAdapter() {
    return defaultDialogInfoAdapter;
  }

  public static void setDefaultDialogInfoAdapter(DialogConfigAdapter defaultDialogInfoAdapter) {
    DialogConfigFactory.defaultDialogInfoAdapter = defaultDialogInfoAdapter;
  }

  private static DialogInfo getDialogInfo(Object subjectId, String tableId) {
    DialogConfigAdapter dialogConfigAdapter = getDialogInfoAdapter(tableId);
    return dialogConfigAdapter.getDialogInfo(subjectId, tableId);
  }

  private static void saveDialogInfo(Object subjectId, DialogInfo DialogInfo) {
    DialogConfigAdapter dialogConfigAdapter = getDialogInfoAdapter(DialogInfo.getId());
    dialogConfigAdapter.saveDialogInfo(subjectId, DialogInfo);
  }

  private static DialogConfigAdapter getDialogInfoAdapter(String tableId) {
    DialogConfigAdapter dialogConfigAdapter = dialogInfoAdapterMap.get(tableId);
    if (dialogConfigAdapter == null) {
      dialogConfigAdapter = defaultDialogInfoAdapter;
    }
    return dialogConfigAdapter;
  }

  private static String getCustomKey(Object subjectId, String dialogId) {
    if (subjectId == null) {
      return dialogId;
    } else {
      return subjectId + "_" + dialogId;
    }
  }

}